home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 5 / BBS in a Box -Volume V (BBS in a Box) (April 1992).iso / Files / Tele / M / MUBBS / Discussions 1.0b.cpt / Discussions ƒ / Discussions source / Discussions.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-02  |  13.2 KB  |  482 lines  |  [TEXT/KAHL]

  1. /*
  2.  *  Discussions.c
  3.  *
  4.  *  This program source code and it's compiled version IS NOT IN THE
  5.  *  PUBLIC DOMAIN ! Please read the "COPYRIGHT NOTICE / WG" file for details
  6.  *  regarding use of this program source code and it's compiled version.
  7.  *
  8.  *  2/2/92 - Modified for Beta test release, N Hawthorn
  9.  *
  10.  */
  11.  
  12.  
  13. #define INMAIN
  14. #include <SetUpA4.h>
  15. #include "MUBBS Module.h"
  16.  
  17. typedef struct    EnterStruct{
  18.                 char FromUser[36];      /* The person who sent the message            */
  19.                 char ToUser[36];        /* The person the message is to               */
  20.                 char title[71];         /* The title of the message                   */
  21.                 int status;             /* 0 = unread    1 = Read     2 = deleted     */
  22.                 char NetAddress[21];    /* Fidonet address of the ToUser(UNUSED)      */
  23.                 char reserved1[21];     /* Reserved, do not use                          */
  24.                 char reserved2[21];     /* Reserved, do not use                          */
  25.                 long int offset;        /* Offset of the message in Email.Text        */
  26.                 long int length;        /* Length of message in chars                 */
  27.                 int numlines;            /* */
  28.                 char DateSent[26];      /* String of Date/Time sent                   */
  29.                 char emailtext[51][82]; /* The text of the email message              */
  30.                 int result;             /* Result to pass back                        */
  31.  
  32.                 };
  33.  
  34. int last_read[maxport]; /* this is a global */
  35.  
  36.  
  37. pascal void main (mode1,G1,P1) /* called from the main routines, and what mode to be in */
  38. int mode1;
  39. struct GS *G1; /* we point to the "global" struct in the Main Module here */
  40. Ptr P1; /* we ignore this pointer, we do not use it at all */
  41. {
  42. Handle temph;
  43. float version = 0.5; /* what version of MUBBS you are compatable with IE: .5 and above */
  44. RememberA0(); SetUpA4(); /* This sets up the A4 register to access our globals */
  45. asm { _RecoverHandle }; asm {move.l a0,temph}; HLock(temph); /* locks our module, do this ! */
  46.  
  47. G=G1; /* This MUST be the first thing you do in main only, it sets up the struct globals */
  48. mode[u]=mode1; /* set up our mode so that you can read it anywhere */
  49.  
  50. switch (mode[u]) { /* any un-handled modes return error from this module */
  51.         case 2:
  52.             msg();
  53.             G->moduleresult=0;
  54.             break;
  55.         case 98:     
  56.               versionck(version); /* just return after this call, don't modify anything */          
  57.              break;
  58.          case 0:
  59.              strcpy (G->programmer,"W Gladnick"); /* show the programmer's name up to 20 chars*/
  60.              G->moduleresult=0; /* this was also a init call if we need close call put 99 here */     
  61.             break;
  62.         default:
  63.             G->moduleresult=1; /* return bad code */
  64.         }
  65. HUnlock(temph); /* unlocks this module, do this ! */
  66. RestoreA4(); /* call this when you are all done */
  67. }
  68.  
  69. msg(){
  70. char temp[256];
  71. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  72. loguser(G->modulename[u]); /* this tells where you are for remote sysop, or writes to log file */
  73.  
  74. /* you print the following so that the sysop can monitor use on the mac screen */
  75.  
  76. print("C> Line %d %s, at: %s\n",(u+1),G->username[u],G->modulename[u]);
  77.  
  78. strcpy(temp,":Dis:");
  79. strcat(temp,G->modulename[u]);
  80. strcat(temp,".intro");
  81.  
  82. sendtext(temp);
  83. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  84.  
  85. loop:
  86. send("]]  *** Discussions Section Menu ***    (currently selected topic \"%s\")]]",G->modulename[u]);
  87.      if (!(cmd1(">> Enter-msg, Read-all, New-msgs, Help, Quit :"))) goto byebye; /* timeout */
  88.           send (G->CR[u]);
  89.                switch (G->input[u]) {
  90.                          case 'E':
  91.                             msg_write();
  92.                             break;
  93.                          case 'R':
  94.                             last_read[u]=0;
  95.                              msg_read();
  96.                              break;
  97.                          case 'N':
  98.                              get_data();
  99.                              msg_read();
  100.                              put_data();
  101.                              break;
  102.                          case 'H':
  103.                             sendtext(":Dis:Discussions.help");
  104.                              break;
  105.                          case 'Q':          /* Quit */
  106.                             return;
  107.                             break;
  108.      }
  109.      if (!G->online[u]) goto byebye; /* log out */
  110.      goto loop;
  111. byebye:
  112. G->online[u]=FALSE; /* show we timed out */
  113.      }
  114.      
  115.  
  116. msg_read(){
  117. unsigned char c;
  118. FILE *stream; /* my message file pointer */
  119. int counter,charcounter;
  120. int i,flag;
  121. char this_user[64],that_user[64],line[82],squiglyStr[5],last_read_str[8];
  122. char temp[256];
  123. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  124.  
  125. counter=0;
  126. strcpy(squiglyStr,"~\n");
  127. strcpy(temp,":Dis:");
  128. strcat(temp,G->modulename[u]);
  129. strcat(temp,".text");
  130.  
  131. if ((stream = fopen(temp,"r")) == NULL) return; /* open the message text file */
  132.  
  133. if (last_read[u]==0) goto skip;
  134.  
  135. while ( TRUE ){ /* read up to message last_read+1 */
  136.     if( fgets(line,79,stream) == NULL ){
  137.         send("]NO NEW MESSAGES]");
  138.         fclose(stream);
  139.         return;
  140.         }
  141.  
  142.     if (strcmp(squiglyStr,line) == 0) ++counter; /* see if it's our end marker */
  143.  
  144.     if (counter == last_read[u]) break; /* stop if we found a new message */
  145.  
  146.     }/* end while*/
  147.  
  148. skip:
  149.  
  150. send (G->CR[u]);
  151. charcounter=0;
  152. flag=TRUE;
  153.  
  154. while ((i = fgetc(stream)) != EOF) {
  155. if (flag) {
  156.     send("____________________________________________________________________]");
  157.     flag=FALSE;
  158.     }
  159.     ++charcounter;
  160.     c = i & 0xFF;
  161.     if (c == '~') {
  162.         fgetc(stream); /* get the last character */
  163.         charcounter=0;
  164.         send("____________________________________________________________________]]");
  165.         ++last_read[u];
  166.         if (!(cmd1(">> Next (or press return), Quit :"))) {G->online[u]=FALSE; return;} /* timeout */
  167.         if (G->input[u] == 'Q') {    /* Quit */
  168.                 fclose(stream);
  169.                 return;
  170.                 }
  171.         goto skip;
  172.         }
  173.     if (charcounter > 80) {
  174.         send(G->CR[u]);
  175.         charcounter=0;
  176.         if ((c == 0x0A) || (c == 0x0D)) continue; /* don't send another CR! */
  177.         }
  178.     if ((c == 0x0A) || (c == 0x0D)) { send(G->CR[u]); charcounter=0;}
  179.     else G->out(c);
  180.     }
  181.     
  182. send("]NO NEW MESSAGES]");
  183. fclose(stream);
  184.  
  185. }/* close msg_read() */
  186.  
  187.  
  188. get_data()
  189. {
  190. /* When this routine is called, it tries to open the users data file   */
  191. /* containing only the number of the last message he read(at this time)*/
  192. /* If the file isn't there, it creates the file and initializes it.    */
  193.  
  194. char data_str[256],user_last_read[128];
  195. FILE *stream;
  196.  
  197. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  198.  
  199. strcpy(data_str,":Dis:");
  200. strcat(data_str,G->username[u]);
  201. strcat(data_str,G->modulename[u]);
  202. strcat(data_str,".data");
  203.  
  204. if ((stream=fopen(data_str,"r")) == NULL){ /* see if the file exists */
  205.     stream=fopen(data_str,"w"); /* create a new file and make it show 0 */
  206.     fputs("0\n",stream);
  207.     last_read[u]=0;
  208.     fclose(stream);
  209.     }
  210. else{
  211.     fgets(user_last_read,18,stream);
  212.     sscanf(user_last_read,"%d",&last_read[u]);
  213.     fclose(stream);
  214.     }
  215. }
  216.  
  217. put_data() /*This routine just updates the users data file*/
  218. {
  219. char data_str[79],user_last_read[20];
  220. FILE *stream;
  221.  
  222. strcpy(data_str,":Dis:");
  223. strcat(data_str,G->username[u]);
  224. strcat(data_str,G->modulename[u]);
  225. strcat(data_str,".data");
  226. stream=fopen(data_str,"w");
  227. sprintf(user_last_read,"%d\n",last_read[u]);
  228. fputs(user_last_read,stream);
  229. fclose(stream);
  230. }
  231.  
  232.  
  233. msg_write()
  234. {
  235. char datetime[256],temp[256];
  236. int i;
  237. char fromstr[512];
  238. char timestr2[128];
  239. FILE *stream;
  240.  
  241. struct EnterStruct S; /* make the struct right here (its now on the stack) */
  242.  
  243. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  244.  
  245. enteremail(&S);
  246.  
  247. if (!G->online[u]) {G->online[u]=FALSE; return;} /* do this check so we can log out if hang up */
  248.  
  249. if (S.result != 10) return; /* 10 means SAVE! */
  250.  
  251. getmytime (datetime);
  252.  
  253. strcpy(temp,":Dis:");
  254. strcat(temp,G->modulename[u]);
  255. strcat(temp,".text");
  256.  
  257. if ((stream = fopen(temp,"a")) == NULL) return; /* if a file isn't there create one */
  258.  
  259. strcpy(fromstr,"From  : ");
  260. strcat(fromstr,G->username[u]);
  261. strcat(fromstr,"\nTo    : All\nTime  : ");
  262. strcat(fromstr,datetime);
  263. strcat(fromstr,"\n\n");
  264.  
  265. fputs(fromstr,stream);
  266.  
  267. i=0;
  268. while ( i <= S.numlines){
  269.     fputs(S.emailtext[i],stream);
  270.     fputs("\n",stream);
  271.     i++;
  272.     }
  273.  
  274. fputs("~\n",stream);
  275. send("]Message saved]");
  276. fclose( stream );
  277. }
  278.  
  279.  
  280. enteremail(S) /* taken from "E-Mail" module source by Noam Freedman */
  281. struct EnterStruct *S;
  282. {
  283. char pad[100]; /* this is a fix for a problem */
  284. char ch;
  285. int a = 0,      /* flag */
  286.     i = 0,        /* temp # holder */
  287.     tf = FALSE,    /* true/false flag */
  288.     num;            /* true/false flag when calling functions */
  289. S->numlines = 0; /* num lines */
  290.     
  291. send("]]A line can contain 75 characters, max 50 lines.]");
  292. send("To end or edit, enter a carriage return on an empty line.]");
  293. send("    ---------1---------2---------3---------4---------5---------6---------7----!]");
  294.  
  295. G->nocheck[u]=TRUE; /* no control checking on ouput ! */
  296. if( (S->numlines+1) < 9 )
  297.     send(" %i: ",(S->numlines+1)); /* don't check for anything here */
  298. else                    
  299.     send("%i: ",(S->numlines+1)); /* don't check for anything here */
  300. G->nocheck[u]=FALSE; /* turn it back on */
  301.     
  302. while ( a == 0 )
  303.     {
  304.     if (!G->in()) {num = 2;goto byebye;} /* carrier detect or time out ? */
  305.     ch = G->input[u];
  306.     if ( ch == '~') continue; /* illegal char for DISCUSSIONS! */
  307.     if ( ch == 13)
  308.         {                                
  309.         G->nocheck[u]=TRUE; /* no control checking on ouput ! */
  310.         send(G->CR[u]); /* don't check for anything here */
  311.         G->nocheck[u]=FALSE; /* turn it back on */
  312.         if (S->numlines >= 49) i = 0;
  313.         else S->numlines = S->numlines + 1;
  314.             
  315.         if (i == 0)
  316.             {
  317.             if(S->numlines <= 48) S->numlines = S->numlines - 2;
  318.             num = askline(S);
  319.             if (num != 0)  goto byebye;
  320.             }
  321.         i = 0;
  322.         S->emailtext[S->numlines][i]= '\0'; 
  323.         G->nocheck[u]=TRUE; /* no control checking on ouput ! */
  324.         if( (S->numlines+1) <= 9 )
  325.             send(" %i: ",(S->numlines+1)); /* don't check for anything here */
  326.         else
  327.             send("%i: ",(S->numlines+1)); /* don't check for anything here */
  328.         G->nocheck[u]=FALSE; /* turn it back on */
  329.         }
  330.     else 
  331.         if ( ch == 8 ) /* handle backspace */
  332.             {
  333.             if (i>0) {
  334.                 G->serout('\b');
  335.                 G->serout(' ');
  336.                 G->serout('\b');
  337.                 i--;
  338.                 S->emailtext[S->numlines][i] = '\0';
  339.                 }
  340.             if (!G->online[u]) {num = 2;goto byebye;} /* time out ? */
  341.             }
  342.     else
  343.         if ( i >= 74 )
  344.             {
  345.             G->serout(ch); /* doesn't check for "S" or "C" */
  346.             if (!G->online[u]) {num = 2;goto byebye;} /* time out ? */
  347.             if (S->numlines >= 49) continue;
  348.             S->emailtext[S->numlines][i] = ch;
  349.             S->emailtext[S->numlines][i+1] = '\0';
  350.             S->numlines = S->numlines + 1;
  351.             i = 0;
  352.             G->nocheck[u]=TRUE; /* no control checking on ouput ! */
  353.             send(G->CR[u]);
  354.             if( (S->numlines+1) <= 9 )
  355.                 send(" %i: ",(S->numlines+1)); /* don't check for anything here */
  356.             else
  357.                 send("%i: ",(S->numlines+1)); /* don't check for anything here */
  358.             G->nocheck[u]=FALSE; /* turn it back on */
  359.             }
  360.     else
  361.         {
  362.         G->serout(ch); /* doesn't check for "S" or "C" */
  363.         if (!G->online[u]) {num = 2;goto byebye;} /* time out ? */
  364.         S->emailtext[S->numlines][i] = ch;
  365.         S->emailtext[S->numlines][i+1] = '\0';
  366.         i++;
  367.         }
  368.     }
  369. byebye:
  370. S->result = num;
  371. }
  372.  
  373.  
  374. askline(S)
  375. struct EnterStruct *S;
  376. {
  377. char tempstring[255], ch;
  378. int num = 0,  /* flag */
  379.     b = 0,  /* flag */
  380.     c = 0,  /* temp variable */
  381.     d = 0;  /* temp variable */
  382.  
  383. while ( b == 0 )
  384.     {                                            
  385.     if (S->numlines == 0 && S->emailtext[0][0] == '\0') /* if no text at all */
  386.         {
  387.         send("]Message Cancelled.]");
  388.         num = 1;
  389.         b = 1;
  390.         break;
  391.         }
  392.     if (!(cmd1("]]>> Continue, Delete line, Edit line, List, Save, Quit : ")))
  393.         {
  394.         G->online[u]=FALSE;
  395.         b = 1;
  396.         num = 2;
  397.         }
  398.     send(G->CR[u]);
  399.     ch = G->input[u];
  400.     switch (ch)
  401.         {
  402.         case 'C':
  403.                 if ( S->numlines <=48 )
  404.                     {
  405.                     S->numlines = S->numlines + 1;
  406.                     num = 0;
  407.                     b = 1;
  408.                     }
  409.                 else
  410.                     send("]Message is already 50 lines!]");
  411.                 break;
  412.         case 'D':
  413.                 send("]Enter line number to delete, or RETURN to exit : ");
  414.                 portsin(tempstring,3);
  415.                 send(G->CR[u]);
  416.                 c = strtoint(tempstring);
  417.                 if (c <= 0) break;
  418.                 if (c > (S->numlines + 1)){
  419.                     send("]]There is no such line number.]]");
  420.                     break;
  421.                     }
  422.                 send("]Line #%d reads:]",c);
  423.                 send(S->emailtext[(c-1)]);
  424.                 cmd1("]]Are you sure you want to DELETE it (Y/N)? ");
  425.                 ch = G->input[u];
  426.                 send(G->CR[u]);
  427.                 if (ch=='Y'){
  428.                     for (d = (c-1); d <S->numlines; d++)
  429.                         strcpy(S->emailtext[d],S->emailtext[d+1]);
  430.                     S->numlines = S->numlines - 1;
  431.                     }
  432.                 else
  433.                     {
  434.                     send("]Line was not deleted.]");
  435.                     }
  436.                 break;
  437.         case 'E':
  438.                 send("]]The edit-line option for the program has been unwritten as of yet.]");
  439.                 break;
  440.         case 'S':
  441.                 if(S->numlines >49) S->numlines=49; /* just to make sure */
  442.                 num = 10;
  443.                 b = 1;
  444.                 break;
  445.         case 'L':
  446.                 for (d = 0;d<=S->numlines && d<=49;d++)
  447.                     {
  448.                     if( (d+1) < 9 )
  449.                         send(" %i: %s]",(d+1),S->emailtext[d]);            
  450.                     else                    
  451.                         send("%i: %s]",(d+1),S->emailtext[d]);
  452.                     if (G->cancel[u]) break; /* did they press cancel? */
  453.                     }
  454.                 send(G->CR[u]);
  455.                 break;
  456.         case 'Q':
  457.                 cmd1("]Are you sure you want to quit (Y/N)? ");
  458.                 ch = G->input[u];
  459.                 send(G->CR[u]);
  460.                 if (ch=='Y')
  461.                     {
  462.                     send("]Message Cancelled.]");
  463.                     num = 1;
  464.                     b = 1;
  465.                     }
  466.                 break;
  467.         }
  468.                     
  469.     }
  470. return(num);
  471. }
  472.  
  473. getmytime(datetime)
  474. char *datetime;
  475. {
  476. char temp[128];
  477. gettime("%I:%M:%S %p  %A %B",temp); /* gets the date & time */
  478. strcpy(datetime,temp);
  479. gettime(" %d %Y (%m/%d/%y)",temp); /* gets the date & time */
  480. strcat(datetime,temp);
  481. }
  482.